﻿using System;
using System.Collections.Generic;
using System.Linq;
using System.Text;
using DDD;
using Xunit;

namespace DokiDokiTest {

    public class TestAttachable {
        [Fact]
        public void Test_New1 () {
            var nod = (Attachable)new Node ();

            Assert.Equal (0, nod.ExecutionOrder);
            Assert.Equal (-1, nod.Scope);
            Assert.Equal (1, nod.Alpha);
            Assert.Equal (true, nod.IsRenderingEnabled);
            Assert.Equal (true, nod.IsPickingEnabled);
            Assert.Equal (true, nod.IsCollisionEnabled);
            Assert.Equal (true, nod.IsLODEnabled);
            Assert.Equal (0, nod.ComponentCount);
        }

        [Fact]
        public void Test_Attach () {
            var nod = (Attachable)new Node ();
            var cmp = new Mesh ();

            nod.Attach (cmp);

            Assert.Equal (1, nod.ComponentCount);
            Assert.Equal (cmp, nod.GetComponent(0));
            Assert.Equal (cmp, nod.GetComponent<Mesh> ());
            Assert.Equal (cmp, nod.As<Mesh>());
            Assert.Equal (true, nod.Is<Mesh> ());            
        }

        [Fact]
        public void Test_Detach () {
            var nod = (Attachable)new Node ();
            var cmp = new Mesh ();

            nod.Attach (cmp);
            nod.Detach (cmp);

            Assert.Equal (0, nod.ComponentCount);
            Assert.Equal (null, nod.GetComponent<Mesh> ());
            Assert.Equal (null, nod.As<Mesh> ());
            Assert.Equal (false, nod.Is<Mesh> ());
        }


        [Fact]
        public void Test_AsIs () {
            var nod = (Attachable)new Node ();
            var cmp1 = new Mesh ();
            var cmp2 = new Camera ();

            nod.Attach (cmp1);
            nod.Attach (cmp2);

            Assert.Equal (2, nod.ComponentCount);

            Assert.Equal (true, nod.Is<Mesh> ());
            Assert.Equal (true, nod.Is<Camera> ());
            Assert.Equal (false, nod.Is<LODSelector> ());

            Assert.Equal (cmp1, nod.As<Mesh> ());
            Assert.Equal (cmp2, nod.As<Camera> ());
            Assert.Equal (null, nod.As<LODSelector> ());
        }

        [Fact]
        public void Test_RecvMessage () {
            var nod = (Attachable)new Node ();
            var cmp1 = new MyTestComponent ();
            var cmp2 = new MyAnotherTestComponent ();

            nod.Attach (cmp1);
            nod.Attach (cmp2);

            nod.RecvMessage ("Set1");

            Assert.Equal (1, cmp1.Value);
            Assert.Equal (1, cmp2.Value);

            nod.RecvMessage ("Set", 2);

            Assert.Equal (2, cmp1.Value);
            Assert.Equal (2, cmp2.Value);

            nod.RecvMessage<MyTestComponent> ("Set1");

            Assert.Equal (1, cmp1.Value);
            Assert.Equal (2, cmp2.Value);

            nod.RecvMessage<MyAnotherTestComponent, int> ("Set", 3);

            Assert.Equal (1, cmp1.Value);
            Assert.Equal (3, cmp2.Value);
        }

        [Fact]
        public void Update () {
            var nod = (Attachable)new Node ();
            var cmp1 = new MyTestComponent ();
            var cmp2 = new MyAnotherTestComponent ();

            nod.Attach (cmp1);
            nod.Attach (cmp2);

            nod.Update (0);

            Assert.Equal (1, cmp1.Value);
            Assert.Equal (1, cmp2.Value);
        }

        // RefleshとSelctのテストは保留

    }
}
